home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / escalant / escala21.lha / escalante2.1 / src / editor / EscalanteCommands.C < prev    next >
C/C++ Source or Header  |  1993-07-15  |  17KB  |  991 lines

  1. //
  2. //    Copyright (C) 1993  Jeff McWhirter
  3. //
  4.  
  5. #include "EscalanteCommands.h"
  6.  
  7. #include "ET++.h"
  8.  
  9. #include "EscalanteView.h"
  10. #include "Escalante.h"
  11.  
  12. #include "VRelation.h"
  13. #include "VEntity.h" 
  14. #include "PtGfx.h"
  15. #include "GfxSet.h"
  16. #include "Geometry.h"
  17.  
  18. #include "ObjectGrid.h"
  19.  
  20. #include "Dialog.h"
  21.  
  22. #include "Window.h"
  23. #include "Token.h"
  24.  
  25.  
  26. DeleterAdder::~DeleterAdder(){
  27. Iter next(&sset);
  28. Object * o;
  29. while( o= next())
  30.     o->RemoveObserver(this); 
  31. next.Reset(&vset);
  32. while( o= next())
  33.     o->RemoveObserver(this); 
  34. }
  35.  
  36.  
  37.  
  38.  
  39. Command *DeleterAdder::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np){
  40.     SetFlag(eCmdMoveEvents,FALSE);
  41.     return this;
  42. }
  43.  
  44.  
  45. void DeleterAdder::Init(){
  46. Iter next(&sset);
  47. Object * o;
  48. while( o= next())
  49.     o->AddObserver(this); 
  50. next.Reset(&vset);
  51. while( o= next())
  52.     o->AddObserver(this); 
  53. }
  54.  
  55.  
  56.  
  57. void    DeleterAdder::DoObserve(int id, int part, void *d , Object *op){
  58. if(op && part == cPartSenderDied) {
  59.     sset.Remove(op); 
  60.     vset.Remove(op);
  61. }
  62. else GraphCommand::DoObserve( id, part,d ,op);
  63. }
  64.  
  65.  
  66.  
  67. void ElementDeleter::DoIt(){
  68. Iter next(&vset);
  69. VGraphElement * vElt;
  70.  
  71. while(vElt = (VGraphElement*)next()) 
  72.     if(vElt->IsKindOf(VGraphElement))
  73.         vElt->SetDead(TRUE);
  74.  
  75. #ifdef USE_STRUCTURAL
  76. next.Reset(&sset);
  77. SGraphElement * selt;
  78. while(selt = (SGraphElement*)next()) 
  79.     if(selt->IsKindOf(SGraphElement))
  80.         selt->SetDead(TRUE);
  81. #endif
  82.  
  83. }
  84.  
  85.     
  86. void ElementDeleter::UndoIt(){
  87. Iter next(&vset);
  88. VGraphElement * vElt;
  89. while(vElt = (VGraphElement*)next()) 
  90.     vElt->SetDead(FALSE); 
  91.  
  92.  
  93.  
  94. #ifdef USE_STRUCTURAL
  95. next.Reset(&sset);
  96. SGraphElement * selt;
  97. while(selt = (SGraphElement*)next()) 
  98.     selt->SetDead(FALSE);
  99. #endif
  100.  
  101. }
  102.  
  103. void ElementDeleter::Commit(){
  104. Iter next(&vset);
  105. VGraphElement * vElt;
  106. while(vElt = (VGraphElement*)next()) {
  107.     vset.Remove(vElt);
  108.     if(vElt->IsDead())
  109.         SafeDelete(vElt);
  110. }
  111.  
  112. #ifdef USE_STRUCTURAL
  113. next.Reset(&sset);
  114. SGraphElement * selt;
  115. while(selt = (SGraphElement*)next()) {
  116.     sset.Remove(selt);
  117.     if(selt->IsDead())
  118.         SafeDelete(selt);
  119. }
  120. #endif
  121. }
  122.  
  123.  
  124.  
  125. void EltAdder::DoIt(){
  126. Iter next(&vset);
  127. VGraphElement * velt;
  128. while(velt = (VGraphElement*)next()) 
  129.     velt->SetDead(FALSE);
  130.  
  131. #ifdef USE_STRUCTURAL
  132. next.Reset(&sset);
  133. SGraphElement * selt;
  134. while(selt = (SGraphElement*)next()) 
  135.     selt->SetDead(FALSE);
  136. #endif
  137. }
  138.  
  139.  
  140.  
  141. void EltAdder::UndoIt(){
  142. Iter next(&vset);
  143. VGraphElement * velt;
  144. while(velt = (VGraphElement*)next()) 
  145.     velt->SetDead(TRUE); 
  146.  
  147.  
  148.  
  149. #ifdef USE_STRUCTURAL
  150. next.Reset(&sset);
  151. SGraphElement * selt;
  152. while(selt = (SGraphElement*)next()) 
  153.     selt->SetDead(TRUE);
  154. #endif
  155. }
  156.  
  157.  
  158. void EltAdder::Commit(){SaveElements();}
  159.  
  160.  
  161.  
  162. void EltAdder::SaveElements(){
  163. Iter next(&vset);
  164. VGraphElement * velt;
  165. while(velt = (VGraphElement*)next()) 
  166.     if(!velt->IsDead()) GetVGraphElementSet()->Add(velt);
  167.     else {
  168.         vset.Remove(velt);
  169.         SafeDelete(velt);
  170.     }
  171.  
  172.  
  173.  
  174. #ifdef USE_STRUCTURAL
  175. next.Reset(&sset);
  176. SGraphElement * selt;
  177. while(selt = (SGraphElement*)next()) 
  178.     if(!selt->IsDead()) GetSGraphElementSet()->Add(selt);
  179.     else {
  180.         sset.Remove(selt);
  181.         SafeDelete(selt);
  182.     }
  183. #endif
  184.  
  185. }
  186.  
  187.  
  188.  
  189.  
  190.  
  191. extern bool gRubberBand;
  192.  
  193. Command *RectDrawer::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np)
  194. {
  195. if(!view) return gNoChanges;
  196. MoverCommand::TrackMouse(tp,ap,pp,np);
  197.     Command::TrackMouse(tp, ap, pp, np);
  198.         switch(tp){
  199.  
  200.         case eTrackRelease:
  201.         case eTrackExit:
  202.         view->DoneDrawingRect();
  203.         return gNoChanges;
  204.  
  205.         case eTrackMove:
  206.         if(OkToMoveTo(np)){
  207.             view->RectDrawn(TRUE);
  208.             view->SetSelectionRect(NormalRect(ap,np));
  209.         }
  210.     default: return this;
  211.         }
  212.     return this;
  213. }
  214.  
  215.  
  216.  
  217.  
  218.  
  219. GroupPicker::GroupPicker(BaseEscalanteView * v,bool newg,Class * c){
  220.     view =v;
  221.     newgroup = newg;
  222.     cl = c;
  223.  
  224.  
  225. }
  226.  
  227. Command *GroupPicker::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np)
  228. {
  229. if(!view) return gNoChanges;
  230.     Command::TrackMouse(tp, ap, pp, np);
  231.         switch(tp){
  232.         case eTrackRelease:
  233.         case eTrackExit:
  234.         if(view){
  235.             if(newgroup)view->SetPickGroup(cl);
  236.             else view->AddToPickGroup(cl);
  237.             view->RectDrawn(FALSE);
  238.         }
  239.  
  240.         return gNoChanges;
  241.  
  242.         case eTrackMove:
  243.             if(view){
  244.                 view->RectDrawn(TRUE);
  245.                 view->SetSelectionRect(NormalRect(ap,np));
  246.             }
  247.             return this;
  248.     default: return this;
  249.         }
  250.     return this;
  251. }
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260. Point EscalanteCommand::DoPoint(Point p){
  261.     Point np=p;
  262.     if(view && view->DoGrid())
  263.         np  =   Point2Grid(p,view->grid);
  264.     return (view? Min(view->GetExtent(),np):np);
  265. }
  266.  
  267.  
  268. void EscalanteCommand::TrackConstrain(Point ap, Point pp, Point *np){
  269.     Command::TrackConstrain( ap, pp, np);
  270.     if(np->x <0) np->x = 0;
  271.     if(np->y <0) np->y = 0;
  272.     if(dopoint)
  273.         *np = DoPoint(*np);
  274. }
  275.  
  276.  
  277.  
  278. void JointMover::MoveBy(Point dp){
  279.     if(!obj) return;
  280.     VGraphElement* elt = (VGraphElement*) obj;
  281.  
  282.     if(doall)elt->AllMoveJointBy(dp,jix);
  283.     else elt->MoveJointBy(dp,jix);
  284.     gChanged();
  285. }
  286.  
  287.  
  288.  
  289.  
  290.  
  291. Command *JointMover::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np)
  292. {
  293.     if(!obj) return gNoChanges;
  294.     VGraphElement* elt = (VGraphElement*) obj;
  295.  
  296.     MoverCommand::TrackMouse(tp, ap, pp, np);
  297.     switch(tp){
  298.     case eTrackExit:
  299.     case eTrackRelease:
  300.         if(view) view->    DoneMovingElement(elt);
  301.         SetFlag(eCmdMoveEvents,FALSE);
  302.         return this;
  303.  
  304.     case eTrackMove:
  305.         Point  dp;
  306.         if(OkToMoveBy(dp,np))
  307.             MoveBy(dp);
  308.     default: return this;
  309. }
  310. return this;
  311. }
  312.  
  313.  
  314.  
  315. Command *ElementMover::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np){
  316.  
  317.     if(!obj) return gNoChanges;
  318.     VGraphElement* elt = (VGraphElement*) obj;
  319.  
  320.     MoverCommand::TrackMouse(tp, ap, pp, np);
  321.     Point dp;
  322.     switch(tp){
  323.     case eTrackExit:
  324.     case eTrackRelease:
  325.         if(view) view->    DoneMovingElement(elt);
  326.         SetFlag(eCmdMoveEvents,FALSE);
  327.         return this;
  328.  
  329.     case eTrackMove:
  330.         if(OkToMoveBy(dp,np))
  331.             MoveBy(dp);
  332.  
  333.     default: return this;
  334.     }
  335. return this;
  336. }
  337.  
  338. void ElementMover::MoveBy(Point dp){
  339.     if(!obj) return;
  340.     VGraphElement* elt = (VGraphElement*) obj;
  341.  
  342.     if(doall) elt->AllMoveBy(dp);
  343.     else     elt->MoveBy(dp);
  344.     gChanged();
  345. }
  346.  
  347.  
  348.  
  349.  
  350. Command *QuickMover::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np)
  351. {
  352.     if(!obj) return gNoChanges;
  353.     VGraphElement* elt = (VGraphElement*) obj;
  354.  
  355.     MoverCommand::TrackMouse(tp, ap, pp, np);
  356.     switch(tp){
  357.     case eTrackExit:
  358.         if(view) view->    DoneMovingElement(elt);
  359.         SetFlag(eCmdMoveEvents,FALSE);
  360.         return this;
  361.  
  362.  
  363.     case eTrackRelease:
  364.         if(!firstrelease)    {firstrelease = TRUE;return this;}
  365.         else {
  366.             Point dp;
  367.             if(OkToMoveBy(dp,np))
  368.                 MoveBy(dp);
  369.             if(view) view->    DoneMovingElement(elt);
  370.             SetFlag(eCmdMoveEvents,FALSE);
  371.             return this;
  372.         }
  373.     default: return this;
  374.     }
  375. return this;
  376. }
  377.  
  378.  
  379.  
  380. void QuickMover::MoveBy(Point dp){
  381.     if(!obj) return;
  382.     VGraphElement* elt = (VGraphElement*) obj;
  383.  
  384.     if(doall) elt->AllMoveBy(dp);
  385.     else     elt->MoveBy(dp);
  386.     gChanged();
  387. }
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395. void    MoverCommand::DoObserve(int id, int part, void *d , Object *op){
  396. if(op && op == obj && part == cPartSenderDied) {obj = 0;}
  397. else MultiVCommand::DoObserve( id, part,d ,op);
  398. }
  399.  
  400.  
  401. void MoverCommand::DoIt(){
  402.     if(doitdelta != gPoint0)
  403.         MoveBy(doitdelta);
  404. }
  405.  
  406. void MoverCommand::UndoIt(){
  407.     if(delta != gPoint0)
  408.         MoveBy(Point(-delta.x,-delta.y));
  409.     doitdelta = delta;
  410. }
  411.  
  412.  
  413.  
  414.  
  415.  
  416. bool MoverCommand::OkToMoveBy(Point & deltaP,Point np){
  417. bool r = (Math::Abs(np.x - lastP.x) >1 || Math::Abs(np.y - lastP.y) >1);
  418. if(r){ 
  419.  
  420.     deltaP = np - lastP;
  421.  
  422.     if(h_or_v  && HOrVType == 0) {    
  423.         if(Math::Abs(deltaP.x) >= Math::Abs(deltaP.y)) HOrVType =1;
  424.         else HOrVType =2;
  425.     }
  426.  
  427.  
  428.     if(HOrVType == 1) 
  429.         deltaP.y =0;
  430.     else     if(HOrVType == 2) 
  431.         deltaP.x = 0;
  432.  
  433.     lastP = np;
  434.     delta += deltaP;
  435. }
  436. return r;
  437. }
  438.  
  439.  
  440.  
  441. bool MoverCommand::OkToMoveTo(Point& np, int coarseness){
  442. bool r =(Math::Abs(np.x - lastP.x) >coarseness || Math::Abs(np.y - lastP.y) >coarseness);
  443. if(r) {
  444.     if(h_or_v && HOrVType == 0) {    
  445.         if(Math::Abs(np.x-lastP.x) >= Math::Abs(np.y-lastP.y)) HOrVType =1;
  446.         else HOrVType =2;
  447.     }
  448.     if(HOrVType == 1) 
  449.         np.y =0;
  450.  
  451.     else     if(HOrVType==2) 
  452.          np.x = 0;
  453.  
  454.     delta += np-lastP;
  455.     lastP = np;
  456. }
  457. return r;
  458. }
  459.  
  460.  
  461.  
  462.  
  463.  
  464. void EltStretcher::MoveBy(Point dp){
  465.     if(!obj) return;
  466.     VGraphElement* elt = (VGraphElement*) obj;
  467.  
  468.     if(doall)elt->AllReshapeBy(dp,lp,ds);
  469.     else elt->ReshapeBy(dp,lp,ds);
  470.     gChanged();
  471. }
  472.  
  473.  
  474.  
  475. Command *EltStretcher::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np){
  476.     
  477.     if(!obj) return gNoChanges;
  478.     VGraphElement* elt = (VGraphElement*) obj;
  479.  
  480.     MoverCommand::TrackMouse(tp, ap, pp, np);
  481.     Point dp = gPoint0;
  482.     switch(tp){
  483.         case eTrackRelease:
  484.         case eTrackExit:
  485.         if(view) view->    DoneMovingElement(elt);
  486.         SetFlag(eCmdMoveEvents,FALSE);
  487.         return this;
  488.  
  489.     case eTrackMove:
  490.         if(OkToMoveBy(dp,np)) 
  491.             MoveBy(dp);
  492.         return this;
  493.  
  494.     default: return this;
  495.     }    
  496.     return this;
  497. }
  498.  
  499.  
  500.  
  501.  
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509. Command *MoverCommand::TrackMouse(TrackPhase, Point , Point , Point np){
  510. if(!DoneFirst()){
  511.     lastP = np;    
  512.     DoneFirst(TRUE);
  513. }
  514. return gNoChanges;
  515. }
  516.  
  517.  
  518.  
  519. void GfxMover::MoveBy(Point dp){
  520.     PtsGfx * gfx = (PtsGfx*) obj;    
  521.     if(!gfx) return;
  522.     gChanged();
  523.     gfx->MoveBy(dp);
  524. }
  525.  
  526.  
  527. Command *GfxMover::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np)
  528. {
  529. if(!obj) return gNoChanges;
  530. //PtsGfx* gfx = (PtsGfx*) obj;
  531.  
  532. MoverCommand::TrackMouse(tp, ap, pp, np);
  533. Point dp;
  534. switch(tp){
  535.     case eTrackExit:
  536.     case eTrackRelease:
  537.         SetFlag(eCmdMoveEvents,FALSE);
  538.         return this;
  539.  
  540.     case eTrackMove:
  541.         if(OkToMoveBy(dp,np))
  542.             MoveBy(dp);
  543.  
  544.     default:return this;
  545. }
  546. return this;
  547. }
  548.  
  549. void GfxStretcher::MoveBy(Point dp){
  550.     gChanged();
  551.     if(!obj) return;
  552.     PtsGfx* gfx = (PtsGfx*) obj;
  553.     gfx->StretchBy(dp,ptix);
  554. }
  555.  
  556. Command *GfxStretcher::TrackMouse(TrackPhase tp,Point ap, Point pp, Point np){
  557. if(!obj) return gNoChanges;
  558. //PtsGfx* gfx = (PtsGfx*) obj;
  559.  
  560. Point dp;
  561. MoverCommand::TrackMouse(tp, ap, pp, np);
  562. switch(tp){
  563.     case eTrackRelease:
  564.     case eTrackExit:
  565.         SetFlag(eCmdMoveEvents,FALSE);
  566.         return this;
  567.     case eTrackMove:
  568.         if(OkToMoveBy(dp,np))
  569.             MoveBy(dp);
  570.  
  571.     default:return this;
  572.     }
  573. return this;
  574. }
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585. Command *Rotator::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np)
  586. {
  587. if(!elt) return gNoChanges;
  588.  
  589.     Command::TrackMouse(tp, ap, pp, np);
  590.         switch(tp){
  591.         case eTrackRelease:
  592.             case eTrackExit:
  593.             return gNoChanges;
  594.         case eTrackPress:
  595.         case eTrackMove:
  596.             if(doall)elt->AllRotateTo(np);
  597.             else elt->RotateTo(np);
  598.             gChanged();
  599.             return this;
  600.     default:return this;
  601.  
  602.         }
  603.     return this;
  604. }
  605.  
  606.  
  607.  
  608.  
  609. RelationAdder::RelationAdder( VRelation * e,VGraphElement * vg,BaseEscalanteView * view ):RelationAdder_BASE(vg,view)
  610. {
  611.     SetFlag(eCmdMoveEvents);
  612.     SetName("Add relation");
  613.     rel = e;
  614.     if(view) view->currentElt = rel;
  615.     firstrelease = FALSE;
  616.     hadrelease = FALSE;
  617. }
  618.  
  619.  
  620.  
  621.  
  622.  
  623. Command * RelationAdder::StoppedAdding(){
  624.     rel->theimage->SetPickable(TRUE);
  625.     if(view) view->currentElt =0;
  626.     {
  627.     Iter next(&vset);
  628.     VGraphElement * tmp;
  629.     while(tmp = (VGraphElement*)next())
  630.         tmp->SetAdding(FALSE);
  631.     }
  632.  
  633.     if(view)
  634.         view->DoneAddingElement(rel);
  635.     SetFlag(eCmdMoveEvents,FALSE);
  636.     return this;
  637. }
  638.  
  639.  
  640. Command *RelationAdder::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np){
  641. VGraphElement * newhd;
  642.  
  643.  
  644. if(!rel) return gNoChanges;
  645.  
  646. if(rel->GetHead()  || !rel->NeedHead()) 
  647.     return StoppedAdding();
  648.  
  649.  
  650. MoverCommand::TrackMouse(tp,ap,pp,np);
  651.     switch(tp){
  652.     case eTrackExit:
  653.         return StoppedAdding();
  654.  
  655.     case eTrackMove:
  656.         if(gRubberBand && OkToMoveTo(np))    
  657.             rel ->AllSetHdPt(np);
  658.         return this;
  659.  
  660.     case eTrackRelease:
  661.         hadrelease = TRUE;
  662.         firstrelease = TRUE;
  663.         return this;
  664.  
  665.     case eTrackPress:
  666.         if(!firstrelease) return this;
  667.         if(gToken.Code == eEvtMiddleButton)    {  // Add joint
  668.             if(hadrelease){
  669.                 rel ->AllSetHdPt(np);
  670.                 rel->AllAddJointLast(np);
  671.             }
  672.             hadrelease = FALSE;
  673.             return this;
  674.         }
  675.         hadrelease = FALSE;
  676.         newhd = rel->GetHead();
  677.         if(!newhd && rel->NeedHead()) {
  678.             if(view){
  679.                 gElementOkFunc = view->GetHeadFunc(rel);
  680.                 view->PickingHd(TRUE);
  681.             }
  682.             newhd= vgraph->FindClosestElement(np,Meta(VGraphElement),20,view);
  683.             if(view) view->PickingHd(FALSE);
  684.             gElementOkFunc=0;
  685.  
  686.             if(newhd) rel->SetHead(newhd);
  687.             else {
  688.                 rel ->AllSetHdPt(np);
  689.                 if(rel->NeedHead() && view) {
  690.                     ErrorReturn r = view->CouldNotFindHead(rel,&vset);
  691.                     if( r == eAbort){
  692.                         view->currentElt =0;
  693.                         view->PickingTl(FALSE);
  694.                         return gNoChanges;
  695.                     }
  696.                     else if( r == eAbortButSaveElements){
  697.                         view->currentElt =0;
  698.                         view->PickingTl(FALSE);
  699.                         SaveElements();
  700.                         return gNoChanges;
  701.                     }
  702.  
  703.  
  704.  
  705.                 }
  706.             }
  707.         }
  708.  
  709.         rel->theimage->SetPickable(TRUE);
  710.         if(view) view->currentElt =0;
  711.         {
  712.     
  713.         Iter next(&vset);
  714.         VGraphElement * tmp;
  715.         while(tmp = (VGraphElement*)next())
  716.             tmp->SetAdding(FALSE);
  717.     
  718.         }
  719.  
  720.         if(view)
  721.             view->DoneAddingElement(rel);
  722.         SetFlag(eCmdMoveEvents,FALSE);
  723.         return this;
  724.  
  725.     default: return this;
  726.  
  727.     }
  728.     return this;
  729. }
  730.  
  731.  
  732.  
  733.  
  734.  
  735. ElementAdder::ElementAdder( VGraphElement * e,
  736.     VGraphElement * vg,
  737.     BaseEscalanteView * view ):ElementAdder_BASE(vg,view){
  738.         SetFlag(eCmdMoveEvents);
  739.         elt = e;
  740.         hadrelease =FALSE;
  741.         firstrelease = FALSE;
  742. }
  743.  
  744.  
  745.  
  746.  
  747. Command *ElementAdder::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np){
  748. if(!elt) return gNoChanges;
  749.  
  750. if(!elt->NeedJoints()){
  751.     {
  752.     Iter next(&vset);
  753.     VGraphElement * tmp;
  754.     while(tmp = (VGraphElement*)next())
  755.         tmp->SetAdding(FALSE);
  756.     }
  757.  
  758.     if(view)
  759.         view->DoneAddingElement(elt);
  760.     SetFlag(eCmdMoveEvents,FALSE);
  761.     return this;
  762. }
  763.  
  764. MoverCommand::TrackMouse(tp,ap,pp,np);
  765.  
  766. switch(tp){
  767.     case eTrackExit:
  768.         {
  769.         Iter next(&vset);
  770.         VGraphElement * tmp;
  771.         while(tmp = (VGraphElement*)next())
  772.             tmp->SetAdding(FALSE);
  773.         }
  774.  
  775.         if(view)
  776.             view->DoneAddingElement(elt);
  777.         SetFlag(eCmdMoveEvents,FALSE);
  778.         return this;
  779.  
  780.     case eTrackMove:
  781.         if(gRubberBand && OkToMoveTo(np))    
  782.             elt ->SetP2(np);
  783.         return this;
  784.  
  785.     case eTrackRelease:
  786.         hadrelease = TRUE;
  787.         firstrelease = TRUE;
  788.         return this;
  789.  
  790.     case eTrackPress:
  791.         if(!firstrelease) return this;
  792.         if(gToken.Code == eEvtMiddleButton)    {  // Add joint
  793.             if(hadrelease){
  794.                 elt ->AllSetP2(np);
  795.                 elt->AllAddJointLast(np);
  796.             }
  797.             hadrelease = FALSE;
  798.             return this;
  799.         }
  800.         else {
  801.             hadrelease = FALSE;
  802.             elt->AllSetP2(np);
  803.             {
  804.             Iter next(&vset);
  805.             VGraphElement * tmp;
  806.             while(tmp = (VGraphElement*)next())
  807.                 tmp->SetAdding(FALSE);
  808.             }
  809.  
  810.             if(view)
  811.                 view->DoneAddingElement(elt);
  812.             SetFlag(eCmdMoveEvents,FALSE);
  813.             return this;
  814.         }
  815.     default: return this;
  816.  
  817.     }
  818.     return this;
  819. }
  820.  
  821.  
  822.  
  823.  
  824. EltSetter::EltSetter( VRelation * e,bool tl, VGraphElement * vg,class Class *cl ,BaseEscalanteView * view):EltSetter_BASE(vg,view) {
  825.     SetFlag(eCmdMoveEvents);
  826.     rel = e;
  827.     firstrelease = FALSE;
  828.     tail = tl;
  829.     c = cl;
  830.     if(c == 0) c = Meta(VGraphElement);
  831.     if(view) view->currentElt = rel;
  832. }
  833.  
  834.  
  835.  
  836. Command *EltSetter::TrackMouse(TrackPhase tp, Point, Point, Point np){
  837.  
  838. if(!rel || !vgraph) return gNoChanges;
  839. switch(tp){
  840.     case eTrackExit: if(view) view->currentElt =0; return gNoChanges;
  841.     case eTrackPress:return this;
  842.     case eTrackRelease:
  843.         if(!firstrelease) {firstrelease = TRUE;return this;}
  844.         if(view) {
  845.             if(tail) view->PickingTl(TRUE);
  846.             else view->PickingHd(TRUE);
  847.         }
  848.  
  849.         VGraphElement * newelt    = vgraph->FindClosestElement(np,c,gGravity,view);
  850.  
  851.         if(view) {
  852.             if(tail) view->PickingTl(FALSE);
  853.             else view->PickingHd(FALSE);
  854.         }
  855.  
  856.         if(newelt== 0 ){
  857.             if(view){
  858.                 view->SignalError( "Could not find appropriate element");
  859.                 view->currentElt =0;
  860.             }
  861.             return gNoChanges;
  862.         }
  863.     
  864.         gChanged();
  865.          if(tail) {rel->SetTail(newelt);}
  866.         else     {rel->SetHead(newelt);}
  867.         if(view) view->currentElt =0;
  868.         return gNoChanges;
  869.  
  870.     default: return this;
  871.     }
  872.     return this;
  873. }
  874.  
  875.  
  876.  
  877.  
  878.  
  879.  
  880.  
  881.  
  882.  
  883.  
  884.  
  885.  
  886. MultiAdder::MultiAdder(VGraphElement * e,
  887.     VGraphElement * vg,
  888.     BaseEscalanteView * view ):MultiAdder_BASE(vg,view){
  889.         SetFlag(eCmdMoveEvents);
  890.         done =0;
  891.         proto = e;
  892.         SetFlag(eCmdMoveEvents,FALSE);
  893. }
  894.  
  895.  
  896.  
  897. #define MAXDONE 2000
  898. int doneX[MAXDONE];
  899. int doneY[MAXDONE];
  900.  
  901.  
  902.  
  903.  
  904. Command *MultiAdder ::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np){
  905. if(!proto) return gNoChanges;
  906.  
  907. MoverCommand::TrackMouse(tp,ap,pp,np);
  908.  
  909.  
  910. switch(tp){
  911.     case eTrackPress:
  912.     case eTrackMove:
  913.         int i;
  914.         for(i=0; (i< done) && (i < MAXDONE); i++)
  915.             if(doneX[i] == np.x  && doneY[i] == np.y) 
  916.                 return this;
  917.  
  918.         if(gNoRepeatAdd){
  919.             ObjectGrid* grid;
  920.             if(view && (grid=view->GetGrid()))
  921.                 if(grid->GetAt(    np)) 
  922.                     return this;    
  923.         }
  924.         if(done  >= MAXDONE) return this;
  925.         {
  926.         doneX[done] = np.x;
  927.         doneY[done++] = np.y;
  928.         Set tmpv;
  929.         Set tmps;
  930.  
  931.         SetCurrentVGraphElementSet(&tmpv);
  932. #ifdef USE_STRUCTURAL
  933.         SetCurrentSGraphElementSet(&tmps);
  934. #endif
  935.         gVProtoList = ((EscalanteView*)view)->allprotos;
  936.  
  937.         VEntity * newEntity = (VEntity*)CloneElt(proto,vgraph,gPoint0);
  938.         gVProtoList = 0;
  939.         SetCurrentVGraphElementSet(0);
  940. #ifdef USE_STRUCTURAL
  941.         SetCurrentSGraphElementSet(0);
  942. #endif
  943.  
  944.         {
  945.         Iter next(&tmpv);
  946.         VGraphElement * tmp;
  947.         Object * obj;
  948.         while(tmp = (VGraphElement*)next()){
  949.             vset.Add(tmp);
  950.             tmp->AddObserver(this);
  951.             tmp->SetAdding(TRUE);
  952.         }
  953. #ifdef USE_STRUCTURAL
  954.         next.Reset(&tmps);
  955.         while(obj = next()){
  956.             obj->AddObserver(this);
  957.             sset.Add(obj);
  958.         }
  959. #endif
  960.  
  961.         }
  962.  
  963.         gChanged();
  964.         newEntity->AllSetOrigin(np);            
  965.         }
  966.         return this;
  967.  
  968.  
  969.  
  970.     case eTrackRelease:
  971.     case eTrackExit:
  972.  
  973.         {
  974.         Iter next(&vset);
  975.         VGraphElement * tmp;
  976.         while(tmp = (VGraphElement*)next())
  977.             tmp->SetAdding(FALSE);
  978.         }
  979.  
  980.         if(view)
  981.             view->DoneAddingElements(&vset);
  982.         return this;
  983.  
  984.  
  985.     default: return this;
  986.  
  987.     }
  988.     return this;
  989. }
  990.  
  991.